﻿using System;
using System.IO;
using System.Text;
using NazTek.Utility;
using System.Xml.Serialization;
using System.Collections.Generic;
using NazTek.Archive.Control.Properties;

namespace NazTek.Archive.Control.Entity
{
    /// <summary>
    /// Encapsulates configurations associated with archiving.
    /// </summary>
    public sealed class ArchiveConfiguration
    {
        /// <summary>
        /// Publishes notification.
        /// </summary>
        public event EventHandler<NoticeEventArgs> Notice;
        /// <summary>
        /// Gets single instance, creating it if necessary.
        /// </summary>
        public static ArchiveConfiguration Instance
        {
            get
            {
                lock (Lock)
                {
                    if (_instance == null)
                        _instance = new ArchiveConfiguration();
                }
                return _instance;
            }
        }
        /// <summary>
        /// Executes <see cref="ServerMetadata.Archive"/> for server discovered in configuration.
        /// </summary>
        public void Archive()
        {
            Notify("Initializing archiver process. . .");
            DatabaseServerList.ForEach(serverMetadata =>
            {
                serverMetadata.Notice += (sender, eventArgs) => Notify(eventArgs.Message);
                serverMetadata.Archive();
            });
            Notify("Successfully completed archiver process.");
        }

        /// <summary>
        /// Gets/sets database servers to archive.
        /// </summary>
        private List<ServerMetadata> DatabaseServerList { get; set; }
        /// <summary>
        /// Lock object, used to enforce singleton.
        /// </summary>
        private static readonly object Lock = new object();
        /// <summary>
        /// Singleton instance.
        /// </summary>
        private static ArchiveConfiguration _instance;
        /// <summary>
        /// De-serializes configuration resource.
        /// </summary>
        private ArchiveConfiguration()
        {
            var config = new XmlSerializer(typeof (List<ServerMetadata>));
            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(Resources.ArchiveConfiguration)))
                DatabaseServerList = config.Deserialize(stream) as List<ServerMetadata>;
        }
        /// <summary>
        /// Publishes notification when there are active subscribers.
        /// </summary>
        /// <param name="message">Message to publish.</param>
        private void Notify(string message)
        {
            if (Notice != null)
                Notice(this, new NoticeEventArgs(message));
        }
    }
}